﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LisaConfigurator
{
    /// <summary>
    /// This class is the implementation of the IConfigurationAccessor interface and contains all the supplementary 
    /// configuration information for the speech recognizer and the TTS Speech engine. 
    /// This supplementary information is kept in two separate maps in the form of key, value pairs.
    /// One Map contains all the supplementary speech recognition information whereas the other map contains all
    /// the supplementary TTS engine information.
    /// </summary>
    public class ConfiguratorImpl:IConfigurationAccessor
    {
        Hashtable speechRecognitionVocabTable;
        Hashtable ttsVocabTable;
        Random random;  //Used to pick random TTS strings to return

        //Keys for speech recognition vocab table
        const String RETURN_TO_STDBY_COMMAND = "Return to Standby";
        const String GRANT_PERMISSION_COMMAND = "Grant permission";
        const String DENY_PERMISSION_COMMAND = "Deny permission";
        const String STATE_CHANGE_PREFIX = "State change prefix";
        const String SCENE_PREFIX = "Scene prefix";

        //Keys for Text-to-speech vocab table
        const String RETURN_TO_STDBY_ON_COMMAND_TTS = "Return to Standby on Command";
        const String RETURN_TO_STDBY_ON_TIMEOUT_TTS = "Return to Standby on Timeout";
        const String CURRENTLY_BUSY_TTS = "Currently busy";
        const String CURRENTLY_BUSY_NEW_STATE_HIGHER_PRIORITY_TTS = "Currently busy, new state higher priority";
        const String PERMISSION_CONFIRMED_TTS = "Permission confirmed";
        const String PERMISSION_DENIED_TTS = "Permission denied";
        const String PERMISSION_TIMEOUT_TTS = "Permission timeout";
        const String USER_COMMAND_RECEIVED_TTS = "User Command Received";
        const String ENVIRONMENT_EVENT_RECEIVED_TTS = "Environment Event Received";

        public ConfiguratorImpl()
        {
            speechRecognitionVocabTable = new Hashtable();
            ttsVocabTable = new Hashtable();
            random = new Random();
            initVocabTables();
        }

        #region Private helper methods
        void initVocabTables()
        {
            //Init Speech recognition table
            List<String> returnToStandbyCommands = new List<String>();
            returnToStandbyCommands.Add("Thank you");
            returnToStandbyCommands.Add("That's enough");
            speechRecognitionVocabTable.Add(RETURN_TO_STDBY_COMMAND, returnToStandbyCommands);
            List<String> grantPermissionCommands = new List<String>();
            grantPermissionCommands.Add("Grant permission");
            grantPermissionCommands.Add("Yes");
            speechRecognitionVocabTable.Add(GRANT_PERMISSION_COMMAND, grantPermissionCommands);
            List<String> denyPermissionCommands = new List<String>();
            denyPermissionCommands.Add("Deny permission");
            denyPermissionCommands.Add("No");
            speechRecognitionVocabTable.Add(DENY_PERMISSION_COMMAND, denyPermissionCommands);
            speechRecognitionVocabTable.Add(STATE_CHANGE_PREFIX, "Lisa ");
            speechRecognitionVocabTable.Add(SCENE_PREFIX, "Scene ");

            //Init TTS table
            List<String> returnToStandbyOnCommandTTS = new List<String>();
            returnToStandbyOnCommandTTS.Add("Certainly.");
            returnToStandbyOnCommandTTS.Add("As you wish.");
            returnToStandbyOnCommandTTS.Add("Of course.");
            ttsVocabTable.Add(RETURN_TO_STDBY_ON_COMMAND_TTS, returnToStandbyOnCommandTTS);
            List<String> returnToStandbyOnTimeoutTTS = new List<String>();
            returnToStandbyOnTimeoutTTS.Add("Returning to standby.");
            returnToStandbyOnTimeoutTTS.Add("Standing by.");
            ttsVocabTable.Add(RETURN_TO_STDBY_ON_TIMEOUT_TTS, returnToStandbyOnTimeoutTTS);
            List<String> currentlyBusyTTS = new List<String>();
            currentlyBusyTTS.Add("I'm currently busy. I will handle your request later.");
            currentlyBusyTTS.Add("I currently have my hands full. I will get to it later.");
            currentlyBusyTTS.Add("Sorry, I'll handle your request later.");
            ttsVocabTable.Add(CURRENTLY_BUSY_TTS, currentlyBusyTTS);
            List<String> currentlyBusyNewStateHigherPriorityTTS = new List<String>();
            currentlyBusyNewStateHigherPriorityTTS.Add("An important event has occurred. I recommend switching to standby so that the new state can be processed.");
            ttsVocabTable.Add(CURRENTLY_BUSY_NEW_STATE_HIGHER_PRIORITY_TTS, currentlyBusyNewStateHigherPriorityTTS);
            List<String> permissionConfirmedTTS = new List<String>();
            permissionConfirmedTTS.Add("As you wish.");
            permissionConfirmedTTS.Add("Certainly.");
            permissionConfirmedTTS.Add("Of course.");
            ttsVocabTable.Add(PERMISSION_CONFIRMED_TTS, permissionConfirmedTTS);
            List<String> permissionDeniedTTS = new List<String>();
            permissionDeniedTTS.Add("As you wish.");
            permissionDeniedTTS.Add("Alright.");
            permissionDeniedTTS.Add("Ok.");
            ttsVocabTable.Add(PERMISSION_DENIED_TTS, permissionDeniedTTS);
            List<String> permissionTimeoutTTS = new List<String>();
            permissionTimeoutTTS.Add("You have not given me permission to switch to the new state yet. I'm going to remain in standby.");
            permissionTimeoutTTS.Add("Since you haven't responded yet, I'll remain in standby.");
            ttsVocabTable.Add(PERMISSION_TIMEOUT_TTS, permissionTimeoutTTS);
            List<String> userCommandReceivedTTS = new List<String>();
            userCommandReceivedTTS.Add("As you wish.");
            userCommandReceivedTTS.Add("Ok.");
            userCommandReceivedTTS.Add("Fo shizzle.");
            ttsVocabTable.Add(USER_COMMAND_RECEIVED_TTS, userCommandReceivedTTS);
            List<String> environmentEventReceivedTTS = new List<String>();
            environmentEventReceivedTTS.Add("I have received an environment event.");
            environmentEventReceivedTTS.Add("Sensor activity detected.");
            environmentEventReceivedTTS.Add("I just received a new environment event.");
            ttsVocabTable.Add(ENVIRONMENT_EVENT_RECEIVED_TTS, environmentEventReceivedTTS);
        }

        /// <summary>
        /// Returns a random entry from the specified list
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        String getRandomListEntry(List<String> list)
        {
            int index = random.Next(list.Count);
            return list[index];
        }

        #endregion

        #region Methods used to access Supplementary Speech Recognition Vocabulary

        /// <summary>
        /// Returns the command used to command lisa back into the standby state.
        /// </summary>
        /// <returns></returns>
        public List<String> getReturnToStandbyCommands()
        {
            return (List<String>)speechRecognitionVocabTable[RETURN_TO_STDBY_COMMAND];
        }

        /// <summary>
        /// Returns the command used to grant permission.
        /// </summary>
        /// <returns></returns>
        public List<String> getGrantPermissionCommands()
        {
            return (List<String>)speechRecognitionVocabTable[GRANT_PERMISSION_COMMAND];
        }

        /// <summary>
        /// Returns the command used to deny permission.
        /// </summary>
        /// <returns></returns>
        public List<String> getDenyPermissionCommands()
        {
            return (List<String>)speechRecognitionVocabTable[DENY_PERMISSION_COMMAND];
        }

        /// <summary>
        /// Returns command-prefix used to invoke a state-change.
        /// </summary>
        /// <returns></returns>
        public String getStateChangePrefix()
        {
            return (String)speechRecognitionVocabTable[STATE_CHANGE_PREFIX];
        }

        /// <summary>
        /// Returns the command-prefix used to invoke a scene-execution.
        /// </summary>
        /// <returns></returns>
        public String getScenePrefix()
        {
            return (String)speechRecognitionVocabTable[SCENE_PREFIX];
        }

        #endregion

        #region Methods used to access Supplementary TTS Vocabulary

        /// <summary>
        /// Returns the TTS String Lisa will say when she returns back to the standby state due to a user command.
        /// </summary>
        /// <returns></returns>
        public String getReturnToStandbyOnCommandTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[RETURN_TO_STDBY_ON_COMMAND_TTS];
            return getRandomListEntry(ttsTexts);
        }

        /// <summary>
        /// Returns the TTS String Lisa will say when she returns back to the standby state due to a timeout.
        /// </summary>
        /// <returns></returns>

        public String getReturnToStandbyOnTimeoutTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[RETURN_TO_STDBY_ON_TIMEOUT_TTS];
            return getRandomListEntry(ttsTexts);
        }
        /// <summary>
        /// Returns the phrase which Lisa will use in the TTS Engine to ask for the user's permission.
        /// </summary>
        /// <param name="newStateName">The name of the new state to which Lisa wants to switch needs to
        /// be passed in the parameters so that it can be incorporated into the TTS string.</param>
        /// <returns></returns>
        public String getUserPermissionRequiredTTS(String newStateName)
        {
            return "I'm supposed to switch to state " + newStateName + ". Is that alright?";
        }

        /// <summary>
        /// Returns the TTS String saying that Lisa is currently busy.
        /// </summary>
        /// <returns></returns>
        public String getCurrentlyBusyTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[CURRENTLY_BUSY_TTS];
            return getRandomListEntry(ttsTexts);
        }

        /// <summary>
        /// Returns the TTS String saying that Lisa is currently busy but that there's a new state with a higher
        /// priority that needs to be taken care of.
        /// </summary>
        /// <returns></returns>
        public String getCurrentlyBusyButNewStateHigherPriorityTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[CURRENTLY_BUSY_NEW_STATE_HIGHER_PRIORITY_TTS];
            return getRandomListEntry(ttsTexts);
        }

        /// <summary>
        /// Returns the TTS String saying that Lisa has received the user's permission confirmation.
        /// </summary>
        /// <returns></returns>
        public String getPermissionConfirmedTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[PERMISSION_CONFIRMED_TTS];
            return getRandomListEntry(ttsTexts);
        }

        /// <summary>
        /// Returns the TTS String saying that Lisa has received the user's permission denial.
        /// </summary>
        /// <returns></returns>
        public String getPermissionDeniedTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[PERMISSION_DENIED_TTS];
            return getRandomListEntry(ttsTexts);
        }

        /// <summary>
        /// Returns the TTS String saying that the user didn't respond quickly enough in regards to the user-permission request.
        /// </summary>
        /// <returns></returns>
        public String getPermissionTimeoutTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[PERMISSION_TIMEOUT_TTS];
            return getRandomListEntry(ttsTexts);
        }

        /// <summary>
        /// Returns the TTS String saying that Lisa received a new user command.
        /// </summary>
        /// <returns></returns>
        public String getUserCommandReceivedTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[USER_COMMAND_RECEIVED_TTS];
            return getRandomListEntry(ttsTexts);
        }

        /// <summary>
        /// Returns the TTS String saying that Lisa received a new environment event.
        /// </summary>
        /// <returns></returns>
        public String getEnvironmentEventReceivedTTS()
        {
            List<String> ttsTexts = (List<String>)ttsVocabTable[ENVIRONMENT_EVENT_RECEIVED_TTS];
            return getRandomListEntry(ttsTexts);
        }

        #endregion
    }
}
